
package hk.ces.oxfam.patch.connection;

import hk.ces.oxfam.patch.db.result.ExcuteStatus;
import hk.ces.oxfam.patch.DBPatchTransaction;
import hk.ces.oxfam.patch.DBPatchTransactionType;
import hk.ces.oxfam.patch.config.Config;
import hk.ces.oxfam.patch.config.Setting;
import hk.ces.oxfam.patch.DBPatchSession;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.log4j.Logger;

/**
 *
 * @author ReutyCheng
 */
public class ConnectionUtil
{
  public static Connection openConnection()
  {
    Connection conn = null;

    try
    {
      Class.forName(Config.CLASS_NAME.toString());
      conn = DriverManager.getConnection(Config.URL.toString(), Config.USER.toString(), Config.PASSWORD.toString());
    }
    catch (SQLException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
    }
    catch (ClassNotFoundException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
    }

    return conn;
  }

  public static void closeResource(Statement statement)
  {
    closeResource(statement, null);
  }

  public static void closeResource(Statement statement, ResultSet resultSet)
  {
    try
    {
      if (statement != null)
      {
        statement.close();
      }
      if (resultSet != null)
      {
        resultSet.close();
      }
    }
    catch (SQLException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
    }
  }

  public static void closeConnection(Connection connection)
  {
    try
    {
      if (connection != null)
      {
        connection.close();
      }
    }
    catch (SQLException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
    }
  }

  public static ExcuteStatus excute(Connection connection)
  {
    if (DBPatchSession.get(DBPatchSession.CURRENT_TRANSACTION_TYPE) == null)
    {
      Class patchClass = (Class) DBPatchSession.get(DBPatchSession.CURRENT_PATCH);
      DBPatchTransaction transaction = (DBPatchTransaction) patchClass.getAnnotation(DBPatchTransaction.class);
      DBPatchSession.put(DBPatchSession.CURRENT_TRANSACTION_TYPE, transaction != null ? transaction.transactionType() : null);
    }

    DBPatchTransactionType transactionType = DBPatchSession.get(DBPatchSession.CURRENT_TRANSACTION_TYPE, DBPatchTransactionType.class);
    if (transactionType == null || transactionType == DBPatchTransactionType.IN_PATCH)
    {
      if (Setting.get().booleanValue.getValue(Setting.ENABLED_COMMIT))
      {
        return ConnectionUtil.commit(connection);
      }
      else
      {
        return ConnectionUtil.rollback(connection);
      }
    }
    else
    {
      return ExcuteStatus.WAIT_TO_ENGINE;
    }
  }

  public static ExcuteStatus commit(Connection connection)
  {
    try
    {
      connection.commit();
      return ExcuteStatus.COMMIT;
    }
    catch (SQLException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
      return rollback(connection);
    }
  }

  public static ExcuteStatus rollback(Connection connection)
  {
    try
    {
      connection.rollback();
      return ExcuteStatus.ROLLBACK;
    }
    catch (SQLException ex)
    {
      Logger.getLogger(ConnectionUtil.class.getName()).error(ex.getMessage(), ex);
      return ExcuteStatus.EXCEPTION;
    }
  }
}
